<?php

class Agilet {
	
	/**
	 * @var Zend_Controller_Request_Http
	 */
	protected $_request;

	/**
	 * @var Agilet
	 */
	private static $_inst;
	
	/**
	 * @var bool
	 */
	private $_isDispatched = false;

	/**
	 * @var int
	 */
	private $_siteId = SITE_ID;
	
	/**
	 * @var array
	 */
	private $_terms = array();
	
	/**
	 * @var Agilet_Dispatcher
	 */
	private $_dispacher = null;
	
	/**
	 * @var Agilet_Bootstrap
	 */
	private $_bootstrap = null;
	
	/**
	 * @var Core_Model_Term
	 */
	private $_currentTerm =  null;
	
	/**
	 * @var string
	 */
	private $_conntrollerName =  '';
	
	/**
	 * @var Agilet_Controller_Action_Abstract
	 */
	private $_controller = NULL;
	
	/**
	 * @return Agilet_Bootstrap
	 */
	public function getBootstrap(){
		if($this->_bootstrap == NULL){
			$this->_bootstrap = new Agilet_Bootstrap;
		}
		
		return $this->_bootstrap;
	}
	
	/**
	 * @return string [system, website]
	 */
	public function getChanel(){
		return $this->_siteId == 1?'system':'website';
	}
	
	/**
	 * @return string public, admin
	 */
	public function getSpace(){
		return 'public';
	}
	
	private $_space = 'public';
	
	/**
	 * @param   string $space
	 * @return  Agilet
	 */
	public function setSpace($space){
		$this->_space = ($space == 'admin')?'admin':'public';
		return $this;
	}
	
	/**
	 * @return int
	 */
	public function getSiteId(){
		return $this->_siteId;
	}
	
	/**
	 * @return Zend_Db_Table_Row_Abstract
	 */
	public function getCurrentTerm(){
		return $this->_currentTerm;
	}
	
	/**
	 * @param  Zend_Db_Table_Row_Abstract  $term
	 * @return Agilet
	 */
	public function appendTerm($term){
		$this->_currentTerm = $term;
		
		array_push($this->_terms,$term);
		return $this;
	}
	
	public function prependTerm($term){
		if(count($this->_terms) ==0){
			$this->_currentTerm = $term;
		}
		
		array_unshift($this->_terms,$term);
		return $this;
	}
	
	/**
	 * @param  int   $site_id
	 * @return Agilet
	 */
	public function setSiteId($site_id){
		$this->_siteId =  $site_id;
		return $this;
	}
	
	private function __construct() {

		spl_autoload_register(array(__CLASS__, "autoload"));

		$this->getBootstrap()->bootstrap();

	}

	/**
	 * @param  string   $model_short_name
	 * @return Zend_Db_Table_Abstract
	 */
	static public function getModel($model_short_name) {
		list($module, $table) = explode('.', $model_short_name);
		$class = $module . '_Model_DbTable_' . $table;
		return new $class;
	}

	/**
	 * @param   string  $item  $module.$table.$id
	 * @return  Zend_Db_Table_Row_Abstract
	 */
	static public function getItem($item) {
		list($model_short_name, $id) = explode(':', $item);
		$model = self::getModel($model_short_name);
		return $model -> find($id) -> current();
	}

	/**
	 * @return Agilet
	 */
	static public function getInst() {
		if (self::$_inst == NULL) {
			self::$_inst = new self;
		}
		return self::$_inst;
	}
	
	public function getDispatcher(){
		if($this->_dispacher == NULL){
			$this->_dispacher = new Agilet_Dispatcher;
		}
		return $this->_dispacher;
	}
	
	/**
	 * process distpach
	 */
	public function dispatch(){
		$this->getDispatcher()->dispatch();
	}

	/**
	 * @return Zend_Controller_Request_Http
	 */
	public function getRequest() {
		if ($this -> _request == NULL) {
			return $this -> _request = new Agilet_Request_Http;
		}
		return $this -> _request;
	}
	
	/**
	 * @return TRUE|FALSE
	 */
	static public function autoload($class) {

		$segments = explode('_', $class);

		$prefix = array_shift($segments);

		if ($prefix == 'Agilet' || $prefix == 'Zend') {
			return
			require LIB_PATH . DS . $prefix . DS . implode('/', $segments) . '.php';
		}
		if(!defined('MODULE_PATH')){
			return false;
		}
		$filename = array_pop($segments) . '.php';
		$path = MODULE_PATH . DS . $prefix;

		if (count($segments)) {
			$dir = array_shift($segments);
			$path .= DS . strtolower($dir) . 's';
		}

		foreach ($segments as $dir) {
			$path .= DS . $dir;
		}

		$path .= DS . $filename;
		if (file_exists($path)) {
			return
			include $path;
		}

		$path = MODULE_PATH . DS . str_replace('_', '/', $class) . '.php';
		if (file_exists($path)) {
			return
			include $path;
		}

		return false;
	}
	
	/**
	 * lowercase format
	 * @return string
	 */
	static public function deflect($string) {
		return strtolower(trim(preg_replace('/([a-z0-9])([A-Z])/', '\1-\2', $string), '-. '));
	}

	/**
	 * cammel case format string
	 * @return string
	 */
	static public function inflect($string) {
		return str_replace(' ', '', ucwords(str_replace(array('.', '-'), ' ', $string)));
	}
	
	/**
	 * process action call
	 * @param  string  $module
	 * @param  string  $controller
	 * @param  string  $action
	 * @param  string  $space 
	 */
	public function process($module, $controller, $action, $space ='public' ){
		if($space){
			$this->setSpace($space);
		}
		
		if($module==null){
			$module = 'core';
		}
		
		if($controller == NULL){
			$controller=  'index';
		}

		if($action == NULL){
			$action =  'index';
		}
		
		$fullController = $space . '-'. $controller;
		
		
		
		$controllerName = $this->_controllerName  =  sprintf('%s_Controller_%s_%s', Agilet::inflect($module), Agilet::inflect($fullController), Agilet::inflect($action));
		$filename = sprintf('%s/controllers/%s/%s', Agilet::inflect($module), Agilet::deflect($fullController), Agilet::deflect($action));
		$filename = MODULE_PATH .  '/' . $filename . '.php';
		
		// echo $filename;
				
		if(!file_exists($filename)){
			echo "file does not exit";
		}else{
			require_once $filename;
		}
		
		$this->_controller = $controller =  new $controllerName;
		
		$request = $this->getRequest();
		
		if($request->isPost() && method_exists($controller, 'post')){
			$controller->post();
		}else{
			$controller->get();
		}
		
		/**
		 * init theme layout etc ...
		 */
		$layout =  new Agilet_Layout;
		return $layout->render();
	}
}
